/*
 * Copyright (c) 2023 Cshoo Org. All Rights Reserved.
 */

package org.cshoo.tattoo.gate.controller;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.CompressionCodecs;
import io.jsonwebtoken.Jws;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import io.jsonwebtoken.security.Keys;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;

import org.cshoo.tattoo.gate.entity.JwtTokenEntity;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import javax.crypto.SecretKey;
import java.util.Date;

/**
 * @author 杨翼
 * @since 1.0
 */
@RestController
@RequestMapping("/token")
@Data
@Slf4j
public class TokenController {

    @Value("${jwt.token.expiration}")
    private long tokenExpiration;

    @Value("${jwt.token.sign.key}")
    private String tokenSignKey;

    @RequestMapping(value = "/refresh", method = RequestMethod.GET)
    public JwtTokenEntity refreshToken(@RequestHeader("Authorization") String authorization) {
        log.debug("authorization:{}", authorization);
        String token = authorization.replaceFirst("Bearer ", "");
        byte[] keyBytes = tokenSignKey.getBytes();
        SecretKey key = Keys.hmacShaKeyFor(keyBytes);
        Jws<Claims> claimsJws = Jwts.parserBuilder().setSigningKey(key).build().parseClaimsJws(token);
        String subject = claimsJws.getBody().getSubject();
        long tokenExpirationTime = System.currentTimeMillis() + tokenExpiration;
        String newToken = Jwts.builder().setSubject(subject)
                .setExpiration(new Date(tokenExpirationTime))
                .signWith(key, SignatureAlgorithm.HS512).compressWith(CompressionCodecs.GZIP).compact();
        log.debug("newToken:{}", newToken);

        JwtTokenEntity jwtToken = new JwtTokenEntity();
        jwtToken.setExpirationTime(tokenExpiration);
        jwtToken.setToken(newToken);

        return jwtToken;
    }
}
